package rest.jbpm.filters;

import rest.jbpm.wrappers.ResourceWrapper;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import javax.xml.bind.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class TagHandler extends DefaultHandler {
	
	private OutputStream out;
	private List<ResourceWrapper> resources;
	private static JAXBContext context = JaxbFilter.context;
	private static Logger log = LoggerFactory.getLogger(TagHandler.class);
	
	public TagHandler(OutputStream out, List<ResourceWrapper> resources) throws JAXBException {
		this.out = out;
		this.resources = resources;
		
	}
	
	private boolean foundRef = false;
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		
		String ref = attributes.getValue("ref");
		log.debug("Found ref {}",ref);
		if(ref != null) {
			for(ResourceWrapper resource : resources){
				if(resource.isUriMatch(ref)) {
					Object res = resource.invoke(ref);
					try {
						if(res != null) {
							foundRef = true;
							Marshaller marshaller = context.createMarshaller();
							marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
							marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
							marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
							marshaller.marshal(res, out);
							return;
						}

					} catch (JAXBException e) {
						log.error("failed to marshal {}",res.getClass().getName(),e);
						throw new SAXException(e);
					}
				}
			}
			
			
		} 
		
		try {
			out.write("<".getBytes("UTF-8"));
			out.write(qName.getBytes("UTF-8"));
			for(int i = 0; i < attributes.getLength(); i++) {
				out.write(" ".getBytes("UTF-8"));
				out.write(attributes.getQName(i).getBytes("UTF-8"));
				out.write("=".getBytes("UTF-8"));
				out.write(("\"" + attributes.getValue(i) + "\"").getBytes("UTF-8"));
			}
			out.write(">".getBytes("UTF-8"));

		} catch (IOException e) {
			throw new SAXException(e);
			
		}
		
	}
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if(foundRef) return;
		// TODO Auto-generated method stub
		String content = new String(ch, start, length);
		try {
			out.write(content.getBytes("UTF-8"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub

		if(foundRef) {
			foundRef = false;
			return;
		}
		
		try {
			out.write("</".getBytes("UTF-8"));
			out.write(qName.getBytes("UTF-8"));
			out.write(">".getBytes("UTF-8"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//super.endElement(uri, localName, qName);
	}

	
	
	

}
